package com.example.lib_base.widget

import android.content.Context
import android.graphics.Bitmap
import android.graphics.drawable.Drawable
import android.util.AttributeSet
import android.view.GestureDetector
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.widget.*
import com.example.lib_base.R


/**
 * 锁屏页
 */
open class PagerLayout @JvmOverloads constructor(
    context: Context,
    attributeSet: AttributeSet? = null,
    defStyleAttr: Int = 0
) :
    LinearLayout(context, attributeSet, defStyleAttr) {
    private var mScroller: Scroller
    private var mGestureDetector: GestureDetector? = null

    // 视图容器
    private var mContainer: View? = null

    // 手指按下时y轴坐标
    private var mDownY = 0f

    // 当前视图是否隐藏
    private var isHidden = false

    // 视图高度
    private var mViewHeight = 0
    private var isBooleanHide: IsBooleanHide? = null

    init {
        // 填充视图
        mContainer = LayoutInflater.from(context).inflate(R.layout.default_view, this, false)
        // 添加视图
        this.addView(mContainer)
        // 初始化Scroller
        mScroller = Scroller(context)
        // 初始化手势检测器
        mGestureDetector = GestureDetector(context, GestureListenerImpl())
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        //获取视图高度
        mViewHeight = MeasureSpec.getSize(heightMeasureSpec)
    }

    override fun computeScroll() {
        if (mScroller.computeScrollOffset()) {
            scrollTo(mScroller.currX, mScroller.currY);
            //必须执行postInvalidate()从而调用computeScroll()
            //其实,在此调用invalidate();亦可
            postInvalidate();
        }
        super.computeScroll()
    }

    override fun onTouchEvent(event: MotionEvent): Boolean {
        // 如果没有隐藏，则可以滑动
        if (!isHidden) {
            when (event.action) {
                MotionEvent.ACTION_DOWN -> {
                    // 获取收按下时的y轴坐标
                    mDownY = event.y
                    return mGestureDetector!!.onTouchEvent(event)
                }
                MotionEvent.ACTION_UP -> {
                    // 获取视图容器滚动的y轴距离
                    val scrollY = this.scrollY
                    // 未超过制定距离，则返回原来位置
                    if (scrollY < 300) {
                        // 准备滚动到原来位置
                        prepareScroll(0, 0)
                    } else { // 超过指定距离，则上滑隐藏
                        // 准备滚动到屏幕上方
                        prepareScroll(0, mViewHeight)
                        // 隐藏
                        isHidden = true
                        isBooleanHide?.isHide(isHidden)
                    }
                }
                MotionEvent.ACTION_MOVE -> {
                    // 获取当前滑动的y轴坐标
                    val curY = event.y
                    // 获取移动的y轴距离
                    val deltaY = curY - mDownY
                    // 阻止视图在原来位置时向下滚动
                    return if (deltaY < 0 || scrollY > 0) {
                        mGestureDetector!!.onTouchEvent(event)
                    } else {
                        true
                    }
                }
                else ->      //其余情况交给GestureDetector手势处理
                    return mGestureDetector!!.onTouchEvent(event)
            }
        }
        return super.onTouchEvent(event)
    }


    // 显示视图
    fun show() {
        isHidden = false
        prepareScroll(0, 0)
    }

    // 隐藏视图
    fun hide() {
        isHidden = true
        prepareScroll(0, mViewHeight)
    }

    //不暴露
    private interface IsBooleanHide {
        fun isHide(hide: Boolean)
    }

    fun setHideListener(isHide: (isHide: Boolean) -> Unit) {
        if (this.isBooleanHide == null) {
            this.isBooleanHide = object : IsBooleanHide {
                override fun isHide(hide: Boolean) {
                    isHide(hide)
                }
            }
        }
    }

    inner class GestureListenerImpl : GestureDetector.OnGestureListener {
        override fun onDown(e: MotionEvent?): Boolean {
            return true
        }

        override fun onShowPress(e: MotionEvent?) {

        }

        override fun onSingleTapUp(e: MotionEvent?): Boolean {
            return false
        }

        //控制拉动幅度:
        //int disY=(int)((distanceY - 0.5)/2);
        //亦可直接调用:
        //smoothScrollBy(0, (int)distanceY);
        override fun onScroll(
            e1: MotionEvent?,
            e2: MotionEvent?,
            distanceX: Float,
            distanceY: Float
        ): Boolean {
            val disY = (distanceY - 0.5) / 2
            beginScroll(0, disY.toInt())
            return false
        }

        override fun onLongPress(e: MotionEvent?) {

        }

        override fun onFling(
            e1: MotionEvent?,
            e2: MotionEvent?,
            velocityX: Float,
            velocityY: Float
        ): Boolean {
            return false
        }

    }

    //滚动到目标位置
    private fun prepareScroll(fx: Int, fy: Int) {
        val dx = fx - mScroller.finalX
        val dy = fy - mScroller.finalY
        beginScroll(dx, dy)
    }


    //设置滚动的相对偏移
    protected fun beginScroll(dx: Int, dy: Int) {
        //第一,二个参数起始位置;第三,四个滚动的偏移量
        mScroller.startScroll(mScroller.finalX, mScroller.finalY, dx, dy)
        //必须执行invalidate()从而调用computeScroll()
        invalidate()
    }


    /**
     * 填充视图
     * @param context
     * @param layoutId
     */
    fun setLayout(context: Context?, layoutId: Int) {
        // 移除所有视图
        removeAllViews()
        // 填充视图
        mContainer = LayoutInflater.from(context).inflate(layoutId, this, false)
        // 添加视图
        this.addView(mContainer)
        // 初始化手势检测器
        if (mGestureDetector == null) {
            mGestureDetector = GestureDetector(context, GestureListenerImpl())
        }
        invalidate()
    }

    /**
     * 设置文本
     * @param viewId
     * @param charSequence
     */
    fun setText(viewId: Int, charSequence: CharSequence?) {
        val textView = getView(viewId) as TextView
        textView.text = charSequence
    }

    /**
     * 设置文本颜色
     * @param viewId
     * @param color
     */
    fun setTextColor(viewId: Int, color: Int) {
        val textView = getView(viewId) as TextView
        textView.setTextColor(color)
    }

    /**
     * 设置文本字体大小
     * @param viewId
     * @param textSize
     */
    fun setTextSize(viewId: Int, textSize: Int) {
        val textView = getView(viewId) as TextView
        textView.textSize = textSize.toFloat()
    }

    /**
     * 设置按钮点击事件
     * @param viewId
     * @param listener
     */
    fun setButtonClickListener(viewId: Int, listener: OnClickListener?) {
        val button: Button = getView(viewId) as Button
        button.setOnClickListener(listener)
    }

    /**
     * 设置图片资源
     * @param viewId
     * @param resId
     */
    fun setImageResource(viewId: Int, resId: Int) {
        if (mContainer != null) {
            val imageView: ImageView = getView(viewId) as ImageView
            imageView.setImageResource(resId)
        }
    }

    /**
     * 设置图片bitmap
     * @param viewId
     * @param bitmap
     */
    fun setImageBitmap(viewId: Int, bitmap: Bitmap?) {
        if (mContainer != null) {
            val imageView: ImageView = getView(viewId) as ImageView
            imageView.setImageBitmap(bitmap)
        }
    }

    /**
     * 设置图片drawable
     * @param viewId
     * @param drawable
     */
    fun setImageDrawable(viewId: Int, drawable: Drawable?) {
        if (mContainer != null) {
            val imageView: ImageView = getView(viewId) as ImageView
            imageView.setImageDrawable(drawable)
        }
    }

    /**
     * 设置图片缩放类型
     * @param viewId
     * @param type
     */
    fun setImageScaleType(viewId: Int, type: ImageView.ScaleType?) {
        if (mContainer != null) {
            val imageView: ImageView = getView(viewId) as ImageView
            imageView.scaleType = type
        }
    }

    /**
     * 设置背景颜色
     * @param color
     */
    override fun setBackgroundColor(color: Int) {
        mContainer!!.setBackgroundColor(color)
    }

    /**
     * 设置背景图片
     * @param background
     */
    override fun setBackground(background: Drawable?) {
        mContainer?.background = background
    }

    /**
     * 设置背景图片资源id
     * @param resId
     */
    override fun setBackgroundResource(resId: Int) {
        mContainer?.setBackgroundResource(resId)
    }

    /**
     * 获取视图控件
     * @param viewId
     * @return
     */
    private fun getView(viewId: Int): View {
        return mContainer!!.findViewById(viewId)
    }
}